#include "stdafx.h"
#include "EXSpinButtonCtrl.h"

// CEXSpinButtonCtrl

IMPLEMENT_DYNAMIC(CEXSpinButtonCtrl, CSpinButtonCtrl)

CEXSpinButtonCtrl::CEXSpinButtonCtrl()
{
	m_bSetUpLeftBitmap = FALSE;
	m_bSetDownRightBitmap = FALSE;

	m_nUpLeftTopHeight = 0;
	m_nUpLeftBottomHeight = 0;
	m_nUpLeftLeftWidth = 0;
	m_nUpLeftRightWidth = 0;

	m_nDownRightTopHeight = 0;
	m_nDownRightBottomHeight = 0;
	m_nDownRightLeftWidth = 0;
	m_nDownRightRightWidth = 0;

	m_nUpLeftBkgndID = 0;
	m_nDownRightBkgndID = 0;

	m_nNumOfBgPics = 0;
	m_crTransparent = RGB(255, 0, 255);
	m_crBkgnd = RGB(0,0,0);
	m_nBkgndID = 0;
	m_bUpLeftFocus = FALSE;
	m_bDownRightFocus = FALSE;
	m_bUpLeftSelect = FALSE;
	m_bDownRightSelect = FALSE;
	m_bTimerSet = FALSE;
	m_bHorizontal = FALSE;
}

CEXSpinButtonCtrl::~CEXSpinButtonCtrl()
{
}


BEGIN_MESSAGE_MAP(CEXSpinButtonCtrl, CSpinButtonCtrl)
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_TIMER()
	ON_MESSAGE(WM_MOUSELEAVE, &CEXSpinButtonCtrl::OnMouseLeaveNotify)
END_MESSAGE_MAP()



// CEXSpinButtonCtrl message handlers

void CEXSpinButtonCtrl::SetResSet(CEXBaseResSet* pResSet)
{
  m_pSpinResSet = (CEXSpinButtonCtrlResSet *)pResSet;

  if(m_pSpinResSet->m_nType == SPIN_CTRL)
  SetBitmaps(m_pSpinResSet->m_arrImgId.GetAt(0), 
  m_pSpinResSet->m_arrImgId.GetAt(1), m_pSpinResSet->m_arrImgId.GetAt(2), 
  m_pSpinResSet->m_nImg_DivideCnt, m_pSpinResSet->m_crBkColor);
}

void CEXSpinButtonCtrl::SetBuddyEdit(CEXEdit* EditBox)
{
  SetBuddy(EditBox);

  CRect rcSeries;
  EditBox->GetWindowRect(rcSeries);
  GetParent()->ScreenToClient(rcSeries);
  rcSeries.right -= 2;
  EditBox->MoveWindow(rcSeries);

}

void CEXSpinButtonCtrl::SetBkgndBitmap(UINT nBkgndID, COLORREF crBkgnd)
{
	m_crBkgnd = crBkgnd;
	m_nBkgndID = nBkgndID;

	CBitmap bmpBkgnd;
	bmpBkgnd.LoadBitmap(m_nBkgndID);

	CDC * pDC = GetDC();

	CDC memDC; 
	memDC.CreateCompatibleDC(pDC);

	CDC srcDC;
	srcDC.CreateCompatibleDC(pDC);

	CBitmap* pOldBitmap1;
	pOldBitmap1 = srcDC.SelectObject(&bmpBkgnd);

	BITMAP bmpinfo;
	bmpBkgnd.GetBitmap(&bmpinfo);
	int bmpWidth = bmpinfo.bmWidth;
	int bmpHeight = bmpinfo.bmHeight;

	CRect rcWnd;
	GetWindowRect(rcWnd);
	ScreenToClient(rcWnd);

	m_bmpBkgnd.DeleteObject();

	CBitmap* pOldBitmap2;
	m_bmpBkgnd.CreateCompatibleBitmap(pDC, rcWnd.Width(), rcWnd.Height());
	pOldBitmap2 = memDC.SelectObject(&m_bmpBkgnd);

	memDC.FillSolidRect(rcWnd, m_crTransparent);

	// entireimage
	if (!memDC.TransparentBlt(3,
		3,
		rcWnd.Width()  - ( 3 + 3 ) ,
		rcWnd.Height() -  ( 3 + 3) ,
		&srcDC,
		3,
		3,
		bmpWidth - ( 3 + 3 ) ,
		bmpHeight - ( 3 + 3 ) , m_crTransparent))
		return;

	// topbar
	if (!memDC.TransparentBlt(3, 0, rcWnd.Width() - (3 + 3), 3,
		&srcDC, 3, 0, bmpWidth - ( 3 + 3) , 3, m_crTransparent))
		return;

	// bottombar
	if (!memDC.TransparentBlt(3, rcWnd.bottom - 3, rcWnd.Width() - ( 3 + 3), 3,
		&srcDC, 3, bmpHeight - 3, bmpWidth - ( 3 + 3) , 3, m_crTransparent ))
		return;

	// sidebar
	if (!memDC.TransparentBlt(0, 3, 3, rcWnd.bottom - 3 - 3 ,
		&srcDC, 0, 3, 3, bmpHeight - ( 3 + 3 ) , m_crTransparent))
		return;

	if (!memDC.TransparentBlt(rcWnd.right - 3 , 3, 3, rcWnd.bottom - 3 - 3 ,
		&srcDC, bmpWidth - 3, 3, 3, bmpHeight - 3 - 3 , m_crTransparent))
		return;

	// lefttop,leftbottom,righttop,rightbottom
	if( !memDC.BitBlt(0, 0, 3, 3, &srcDC, 0, 0, SRCCOPY) )
		return;

	if( !memDC.BitBlt(0, rcWnd.bottom - 3, 3, 3, 
		&srcDC, 0, bmpHeight - 3, SRCCOPY) )
		return;

	if( !memDC.BitBlt(rcWnd.right - 3, 0, 3, 3, 
		&srcDC, bmpWidth - 3, 0, SRCCOPY) )
		return;

	if( !memDC.BitBlt(rcWnd.right - 3, rcWnd.bottom - 3, 3, 3,
		&srcDC, bmpWidth - 3, bmpHeight - 3, SRCCOPY) )
		return;

	srcDC.SelectObject(pOldBitmap1);
	memDC.SelectObject(pOldBitmap2);

	ReleaseDC(pDC);
	ReleaseDC(&srcDC);
	ReleaseDC(&memDC);

	Invalidate(FALSE);
}

BOOL CEXSpinButtonCtrl::SetUpLeftBitmaps(UINT nBkgndID, UINT nUpLeftID, 
                                         int nCount, COLORREF crBkgnd, 
                                         int nTopHeight /* = 0*/, 
                                         int nBottomHeight /* = 0*/, 
                                         int nLeftWidth /* = 0*/, 
                                         int nRightWidth /* = 0*/)
{
	m_nUpLeftTopHeight = nTopHeight;
	m_nUpLeftBottomHeight = nBottomHeight;
	m_nUpLeftLeftWidth = nLeftWidth;
	m_nUpLeftRightWidth = nRightWidth;

	m_nUpLeftBkgndID = nBkgndID;
	m_nUpLeftID = nUpLeftID;
	m_nNumOfBgPics  = nCount;  
  
	CRect rcWnd;
	GetWindowRect(rcWnd);
	ScreenToClient(rcWnd);

	if (GetParent()->IsKindOf(RUNTIME_CLASS(CDateTimeCtrl)))
		rcWnd.DeflateRect(0, 0, 1, 1);

	m_rcUpLeft = rcWnd;
	m_rcDownRight = rcWnd;

	if (m_bHorizontal)
	{
		int nSize = rcWnd.Width();
		m_rcUpLeft.right = m_rcUpLeft.left + (nSize/2);
		m_rcDownRight.left = rcWnd.right - (nSize/2);
	}
	else
	{
		int nSize = rcWnd.Height();
		m_rcUpLeft.bottom = m_rcUpLeft.top + (nSize/2);
		m_rcDownRight.top = rcWnd.bottom - (nSize/2);
	}

	CBitmap bmpTemp;
	if( !bmpTemp.LoadBitmap(m_nUpLeftBkgndID) )
		return FALSE;

	CBitmap bmpUpLeft;
	if( !bmpUpLeft.LoadBitmap(m_nUpLeftID) )
		return FALSE;

	int nExtra = 0;

	if (GetBuddy())
		nExtra = 3;

	m_bmpUpLeft.DeleteObject();

	if( !InitBgBitmap( bmpTemp, bmpUpLeft, m_bmpUpLeft, normal, m_nNumOfBgPics, 
    TRUE, nTopHeight, nBottomHeight, nLeftWidth, nRightWidth, nExtra) ) 
		return FALSE;

	if( !InitBgBitmap( bmpTemp, bmpUpLeft, m_bmpUpLeft, focus, m_nNumOfBgPics, 
    TRUE, nTopHeight, nBottomHeight, nLeftWidth, nRightWidth, nExtra) )
		return FALSE;

	if( !InitBgBitmap( bmpTemp, bmpUpLeft, m_bmpUpLeft, select, m_nNumOfBgPics, 
    TRUE, nTopHeight, nBottomHeight, nLeftWidth, nRightWidth, nExtra) )
		return FALSE;

	if( !InitBgBitmap( bmpTemp, bmpUpLeft, m_bmpUpLeft, disable, m_nNumOfBgPics, 
    TRUE, nTopHeight, nBottomHeight, nLeftWidth, nRightWidth, nExtra) )
		return FALSE;

	m_bSetUpLeftBitmap = TRUE;

	return TRUE;
}

BOOL CEXSpinButtonCtrl::SetDownRightBitmaps(UINT nBkgndID, UINT nDownRightID, 
                                            int nCount, COLORREF crBkgnd, 
                                            int nTopHeight /* = 0*/, 
                                            int nBottomHeight /* = 0*/, 
                                            int nLeftWidth /* = 0*/, 
                                            int nRightWidth /* = 0*/)
{
	m_nDownRightTopHeight = nTopHeight;
	m_nDownRightBottomHeight = nBottomHeight;
	m_nDownRightLeftWidth = nLeftWidth;
	m_nDownRightRightWidth = nRightWidth;

	m_nDownRightBkgndID = nBkgndID;
	m_nDownRightID = nDownRightID;
	m_nNumOfBgPics  = nCount;  

	CRect rcWnd;
	GetWindowRect(rcWnd);
	ScreenToClient(rcWnd);

	if (GetParent()->IsKindOf(RUNTIME_CLASS(CDateTimeCtrl)))
		rcWnd.DeflateRect(0, 0, 1, 1);

	m_rcUpLeft = rcWnd;
	m_rcDownRight = rcWnd;

	if (m_bHorizontal)
	{
		int nSize = rcWnd.Width();
		m_rcUpLeft.right = m_rcUpLeft.left + (nSize/2);
		m_rcDownRight.left = rcWnd.right - (nSize/2);
	}
	else
	{
		int nSize = rcWnd.Height();
		m_rcUpLeft.bottom = m_rcUpLeft.top + (nSize/2);
		m_rcDownRight.top = rcWnd.bottom - (nSize/2);
	}

	CBitmap bmpTemp;
	if( !bmpTemp.LoadBitmap(m_nDownRightBkgndID) )
		return FALSE;

	CBitmap bmpDownRight;
	if( !bmpDownRight.LoadBitmap(m_nDownRightID) )
		return FALSE;

	int nExtra = 0;

	if (GetBuddy())
		nExtra = 3;

	m_bmpDownRight.DeleteObject();

	if( !InitBgBitmap( bmpTemp, bmpDownRight, m_bmpDownRight, normal, 
    m_nNumOfBgPics, FALSE, nTopHeight, nBottomHeight, nLeftWidth, nRightWidth, 
    nExtra * -1) ) 
		return FALSE;

	if( !InitBgBitmap( bmpTemp, bmpDownRight, m_bmpDownRight, focus, 
    m_nNumOfBgPics, FALSE, nTopHeight, nBottomHeight, nLeftWidth, nRightWidth, 
    nExtra * -1) )
		return FALSE;

	if( !InitBgBitmap( bmpTemp, bmpDownRight, m_bmpDownRight, select, 
    m_nNumOfBgPics, FALSE, nTopHeight, nBottomHeight, nLeftWidth, nRightWidth, 
    nExtra * -1) )
		return FALSE;

	if( !InitBgBitmap( bmpTemp, bmpDownRight, m_bmpDownRight, disable, 
    m_nNumOfBgPics, FALSE, nTopHeight, nBottomHeight, nLeftWidth, nRightWidth, 
    nExtra * -1) )
		return FALSE;

	m_bSetDownRightBitmap = TRUE;

	return TRUE;
}

BOOL CEXSpinButtonCtrl::SetBitmaps(UINT nBkgndID, UINT nUpLeftID, 
                                   UINT nDownRightID, int nCount, 
                                   COLORREF crBkgnd, int nTopHeight /* = 0*/, 
                                   int nBottomHeight /* = 0*/, 
                                   int nLeftWidth /* = 0*/, 
                                   int nRightWidth /* = 0*/)
{
	if (!SetUpLeftBitmaps(nBkgndID, nUpLeftID, nCount, crBkgnd, nTopHeight, 
    nBottomHeight, nLeftWidth, nRightWidth))
		return FALSE;

	if (!SetDownRightBitmaps(nBkgndID, nDownRightID, nCount, crBkgnd, nTopHeight, 
    nBottomHeight, nLeftWidth, nRightWidth))
		return FALSE;

	return TRUE;
}

BOOL CEXSpinButtonCtrl::InitBgBitmap(CBitmap & src, CBitmap & bmpBtn, 
                                     CBitmap & dist, int index, int count, 
                                     BOOL bUp, int nTopHeight /* = 0*/, 
                                     int nBottomHeight /* = 0*/, 
                                     int nLeftWidth /* = 0*/, 
                                     int nRightWidth2 /* = 0*/, 
                                     int nExtra /* = 0*/)
{
	CDC * pDC = GetDC();

	CDC memDC; 
	memDC.CreateCompatibleDC(pDC);

	CDC srcDC;
	srcDC.CreateCompatibleDC(pDC);

	CBitmap* pOldBitmap1;
	pOldBitmap1 = srcDC.SelectObject(&src);

	BITMAP bmpinfo;
	src.GetBitmap(&bmpinfo);
	int bmpWidth = bmpinfo.bmWidth / count;
	int bmpHeight = bmpinfo.bmHeight;
	int orix = bmpWidth * (index < count ? index : 0);

 	CRect rc(m_rcUpLeft);

	if (!dist.GetSafeHandle())
		dist.CreateCompatibleBitmap(pDC, rc.Width()*count, rc.Height());

	CBitmap bmpTemp;
	bmpTemp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());

	CBitmap* pOldBitmap2;
	pOldBitmap2 = memDC.SelectObject(&bmpTemp);

	memDC.FillSolidRect(rc, m_crTransparent);
  
  if(!nTopHeight && !nBottomHeight && !nLeftWidth && !nRightWidth2)
    memDC.StretchBlt(0,0,rc.Width(),rc.Height(),
                    &srcDC, orix, 0, bmpWidth, bmpHeight, SRCCOPY);
  else
  {
	  // entireimage
	  memDC.TransparentBlt(nLeftWidth,
		nTopHeight,
		rc.Width()  - ( nLeftWidth + nRightWidth2 ) ,
		rc.Height() -  ( nTopHeight + nBottomHeight) ,
		&srcDC,
		orix + nLeftWidth,
		nTopHeight,
		bmpWidth - ( nLeftWidth + nRightWidth2 ) ,
		bmpHeight - ( nTopHeight + nBottomHeight ) , m_crTransparent);

	  // topbar
	  memDC.TransparentBlt(nLeftWidth,0, rc.Width() - (nLeftWidth + nRightWidth2), 
      nTopHeight, &srcDC,orix + nLeftWidth, 0, bmpWidth - 
      ( nLeftWidth + nRightWidth2) , nTopHeight, m_crTransparent);

	  // bottombar
	  memDC.TransparentBlt(nLeftWidth, rc.bottom - nBottomHeight, rc.Width() - 
      ( nLeftWidth + nRightWidth2), nBottomHeight, &srcDC,orix + nLeftWidth, 
      bmpHeight - nBottomHeight, bmpWidth - ( nLeftWidth + nRightWidth2), 
      nBottomHeight, m_crTransparent );

	  // sidebar
	  memDC.TransparentBlt(0, nTopHeight, nLeftWidth, rc.bottom - nTopHeight - 
      nBottomHeight, &srcDC, orix, nTopHeight, nLeftWidth, bmpHeight - 
      ( nTopHeight + nBottomHeight ) , m_crTransparent);

	  memDC.TransparentBlt(rc.right - nRightWidth2 , nTopHeight, nRightWidth2, 
      rc.bottom - nTopHeight - nBottomHeight,	&srcDC, orix +  bmpWidth - 
      nRightWidth2, nTopHeight, nRightWidth2, bmpHeight - nTopHeight - 
      nBottomHeight , m_crTransparent);

	  // lefttop,leftbottom,righttop,rightbottom
	  if( !memDC.BitBlt(0, 0, nLeftWidth, nTopHeight, &srcDC, orix, 0, SRCCOPY) )
		  return FALSE;

	  if( !memDC.BitBlt(0, rc.bottom - nBottomHeight, nLeftWidth, nBottomHeight, 
		  &srcDC, orix, bmpHeight - nBottomHeight, SRCCOPY) )
		  return FALSE;

	  if( !memDC.BitBlt(rc.right - nRightWidth2, 0, nRightWidth2, nTopHeight, 
		  &srcDC, orix + bmpWidth - nRightWidth2, 0, SRCCOPY) )
		  return FALSE;

	  if( !memDC.BitBlt(rc.right - nRightWidth2, rc.bottom - nBottomHeight, 
      nRightWidth2, nBottomHeight, &srcDC, orix + bmpWidth - nRightWidth2, 
      bmpHeight - nBottomHeight, SRCCOPY) )
		  return FALSE;
  }

	bmpBtn.GetBitmap(&bmpinfo);
	int bmpBtnWidth = bmpinfo.bmWidth / count;
	int bmpBtnHeight = bmpinfo.bmHeight;
	int Btnorix = bmpBtnWidth * (index < count ? index : 0);

	CDC bmpBtnDC;
	bmpBtnDC.CreateCompatibleDC(pDC);

	CBitmap * pOldBmpBtn = NULL;
	pOldBmpBtn = bmpBtnDC.SelectObject(&bmpBtn);

	int nOffX = (rc.Width()+(abs(nExtra)*-1)-bmpBtnWidth)/2;
	int nOffY = (rc.Height()+nExtra-bmpBtnHeight)/2;

  if (m_bHorizontal)
  {
    nOffX += (bUp ? (rc.Width()-bmpBtnWidth)%2 : 0);
  }
  else
  {
    nOffY += (bUp ? (rc.Height()-bmpBtnHeight)%2 : 0);
  }
  
	memDC.TransparentBlt(nOffX, nOffY, bmpBtnWidth, bmpBtnHeight, 
    &bmpBtnDC, Btnorix, 0, bmpBtnWidth, bmpBtnHeight, m_crTransparent);

	CDC dcArrow;
	dcArrow.CreateCompatibleDC(pDC);

	CBitmap * pOldBitmap3 = dcArrow.SelectObject(&dist);

	dcArrow.BitBlt(rc.Width()*index, 0, rc.Width(), rc.Height(), 
    &memDC, 0, 0, SRCCOPY);

	bmpBtnDC.SelectObject(pOldBmpBtn);
	srcDC.SelectObject(pOldBitmap1);
	memDC.SelectObject(pOldBitmap2);
	dcArrow.SelectObject(pOldBitmap3);

	ReleaseDC(pDC);
	ReleaseDC(&srcDC);
	ReleaseDC(&memDC);

	return TRUE;
}

void CEXSpinButtonCtrl::OnSize(UINT nType, int cx, int cy)
{
	CSpinButtonCtrl::OnSize(nType, cx, cy);

	if (IsWindow(GetSafeHwnd()) && m_bSetUpLeftBitmap && m_bSetDownRightBitmap)
	{
		if (m_nBkgndID)
			SetBkgndBitmap(m_nBkgndID, m_crBkgnd);

		VERIFY(SetUpLeftBitmaps(m_nUpLeftBkgndID, m_nUpLeftID, m_nNumOfBgPics, 
      m_crTransparent, m_nUpLeftTopHeight, m_nUpLeftBottomHeight, 
      m_nUpLeftLeftWidth, m_nUpLeftRightWidth));

		VERIFY(SetDownRightBitmaps(m_nDownRightBkgndID, m_nDownRightID, 
      m_nNumOfBgPics, m_crTransparent, m_nDownRightTopHeight, 
      m_nDownRightBottomHeight, m_nDownRightLeftWidth, m_nDownRightRightWidth));
	}
}

void CEXSpinButtonCtrl::DrawUpLeftFrame(CDC * pDC)
{
	if (!m_bSetUpLeftBitmap)
		return;

	BOOL bAlloc = FALSE;
	if (!pDC)
	{
		pDC = GetDC();
		bAlloc = TRUE;
	}

	CDC dcBkgnd;
	dcBkgnd.CreateCompatibleDC(pDC);

	CBitmap bmpBkgnd;
	bmpBkgnd.CreateCompatibleBitmap(pDC, m_rcUpLeft.Width(), m_rcUpLeft.Height());

	CBitmap * pOldBmpBkgnd = NULL;
	pOldBmpBkgnd = dcBkgnd.SelectObject(&bmpBkgnd);

	CDC dcImage;
	dcImage.CreateCompatibleDC(pDC);

	CBitmap* pOldBgBitmapImage = NULL;
	pOldBgBitmapImage  = dcImage.SelectObject(&m_bmpUpLeft);

	STATUS st;

	if (!IsWindowEnabled())
	{
		st = disable;
	}
	else if (m_bUpLeftSelect)
	{
		st = select;
	}
	else if (m_bUpLeftFocus)
	{
		st = focus;
	}
	else
	{
		st = normal;
	}

	dcBkgnd.BitBlt(0, 0, m_rcUpLeft.Width(), m_rcUpLeft.Height(), &dcImage, 
    m_rcUpLeft.Width()*st, 0, SRCCOPY);

	dcImage.SelectObject(pOldBgBitmapImage);

	pDC->TransparentBlt(m_rcUpLeft.left, m_rcUpLeft.top, m_rcUpLeft.Width(), 
    m_rcUpLeft.Height(), &dcBkgnd, 0, 0, m_rcUpLeft.Width(), 
    m_rcUpLeft.Height(), m_crTransparent);

	dcBkgnd.SelectObject(pOldBmpBkgnd);

	if (bAlloc)
		ReleaseDC(pDC);
}

void CEXSpinButtonCtrl::DrawDownRightFrame(CDC * pDC)
{
	if (!m_bSetDownRightBitmap)
		return;

	BOOL bAlloc = FALSE;
	if (!pDC)
	{
		pDC = GetDC();
		bAlloc = TRUE;
	}

	CDC dcBkgnd;
	dcBkgnd.CreateCompatibleDC(pDC);

	CBitmap bmpBkgnd;
	bmpBkgnd.CreateCompatibleBitmap(pDC, m_rcDownRight.Width(), 
    m_rcDownRight.Height());

	CBitmap * pOldBmpBkgnd = NULL;
	pOldBmpBkgnd = dcBkgnd.SelectObject(&bmpBkgnd);

	CDC dcImage;
	dcImage.CreateCompatibleDC(pDC);

	CBitmap* pOldBgBitmapImage = NULL;
	pOldBgBitmapImage  = dcImage.SelectObject(&m_bmpDownRight);

	STATUS st;

	if (!IsWindowEnabled())
	{
		st = disable;
	}
	else if (m_bDownRightSelect)
	{
		st = select;
	}
	else if (m_bDownRightFocus)
	{
		st = focus;
	}
	else
	{
		st = normal;
	}

	dcBkgnd.BitBlt(0, 0, m_rcDownRight.Width(), m_rcDownRight.Height(), 
    &dcImage, m_rcDownRight.Width()*st, 0, SRCCOPY);
	dcImage.SelectObject(pOldBgBitmapImage);

	pDC->TransparentBlt(m_rcDownRight.left, m_rcDownRight.top, 
    m_rcDownRight.Width(), m_rcDownRight.Height(), &dcBkgnd, 0, 0, 
    m_rcDownRight.Width(), m_rcDownRight.Height(), m_crTransparent);

	dcBkgnd.SelectObject(pOldBmpBkgnd);

	if (bAlloc)
		ReleaseDC(pDC);
}

BOOL CEXSpinButtonCtrl::OnEraseBkgnd(CDC* pDC)
{
	if (m_bSetUpLeftBitmap && m_bSetDownRightBitmap)
	{
		CWindowDC dc(this);

		CRect rcWnd;
		GetWindowRect(rcWnd);

		if (m_nBkgndID)
		{
			BITMAP bm;
			m_bmpBkgnd.GetBitmap(&bm);

			CDC dcImage;
			dcImage.CreateCompatibleDC(&dc);

			CBitmap * pOldBmpImage = NULL;
			pOldBmpImage = dcImage.SelectObject(&m_bmpBkgnd);

			dc.FillSolidRect(0, 0, rcWnd.Width(), rcWnd.Height(), m_crBkgnd);
			dc.TransparentBlt(0, 0, rcWnd.Width(), rcWnd.Height(), &dcImage, 0, 0, 
        bm.bmWidth, bm.bmHeight, m_crTransparent);

			dcImage.SelectObject(pOldBmpImage);
		}

		DrawUpLeftFrame(&dc);
		DrawDownRightFrame(&dc);

		Invalidate(FALSE);

		return FALSE;
	}

	return CSpinButtonCtrl::OnEraseBkgnd(pDC);
}

void CEXSpinButtonCtrl::PreSubclassWindow()
{
	if (GetStyle() & UDS_HORZ)
		m_bHorizontal = TRUE;

	CSpinButtonCtrl::PreSubclassWindow();

}

LRESULT CEXSpinButtonCtrl::WindowProc(UINT message, WPARAM wParam,LPARAM lParam)
{
	if (message == WM_PAINT && m_bSetUpLeftBitmap && m_bSetDownRightBitmap)
	{
		CPaintDC dc(this);

		CRect rcWnd;
		GetWindowRect(rcWnd);

		if (m_nBkgndID)
		{
			BITMAP bm;
			m_bmpBkgnd.GetBitmap(&bm);

			CDC dcImage;
			dcImage.CreateCompatibleDC(&dc);

			CBitmap * pOldBmpImage = NULL;
			pOldBmpImage = dcImage.SelectObject(&m_bmpBkgnd);

			dc.FillSolidRect(0, 0, rcWnd.Width(), rcWnd.Height(), m_crBkgnd);
			dc.TransparentBlt(0, 0, rcWnd.Width(), rcWnd.Height(), &dcImage, 
        0, 0, bm.bmWidth, bm.bmHeight, m_crTransparent);

			dcImage.SelectObject(pOldBmpImage);
		}

		DrawUpLeftFrame(&dc);
		DrawDownRightFrame(&dc);

		return FALSE;
	}

	return CSpinButtonCtrl::WindowProc(message, wParam, lParam);
}

void CEXSpinButtonCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
	SetCapture();

	m_bUpLeftSelect = FALSE;
	m_bDownRightSelect = FALSE;

	if (m_rcUpLeft.PtInRect(point))
	{
		m_bUpLeftSelect = TRUE;
		Invalidate(FALSE);
	}
	else if (m_rcDownRight.PtInRect(point))
	{
		m_bDownRightSelect = TRUE;
		Invalidate(FALSE);
	}

	CSpinButtonCtrl::OnLButtonDown(nFlags, point);
}

void CEXSpinButtonCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
	ReleaseCapture();

	m_bUpLeftSelect = FALSE;
	m_bDownRightSelect = FALSE;

	Invalidate(FALSE);

	CSpinButtonCtrl::OnLButtonUp(nFlags, point);
}

void CEXSpinButtonCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
	TRACKMOUSEEVENT tme = {0};
	tme.cbSize = sizeof tme;
	tme.dwFlags = TME_LEAVE;
	tme.hwndTrack = GetSafeHwnd();
	tme.dwHoverTime = 10;

	TrackMouseEvent(&tme);

	m_bUpLeftFocus = FALSE;
	m_bDownRightFocus = FALSE;
	m_bUpLeftSelect = FALSE;
	m_bDownRightSelect = FALSE;

	if (m_rcUpLeft.PtInRect(point))
	{
		if (nFlags & MK_LBUTTON)
			m_bUpLeftSelect = TRUE;
		else
			m_bUpLeftFocus = TRUE;
	}
	else if (m_rcDownRight.PtInRect(point))
	{
		if (nFlags & MK_LBUTTON)
			m_bDownRightSelect = TRUE;
		else
			m_bDownRightFocus = TRUE;
	}
	Invalidate(FALSE);

	CSpinButtonCtrl::OnMouseMove(nFlags, point);
}

LRESULT CEXSpinButtonCtrl::OnMouseLeaveNotify(WPARAM w, LPARAM l)
{
	m_bUpLeftFocus = FALSE;
	m_bDownRightFocus = FALSE;
	Invalidate(FALSE);

	return 0;
}

void CEXSpinButtonCtrl::OnTimer(UINT_PTR nIDEvent)
{
	if (nIDEvent == IDT_MOUSE_LEAVE)
	{
		POINT pt;
		GetCursorPos(&pt);
		ScreenToClient(&pt);

		TRACE(L"\nUPLEFT - %s     ", m_rcUpLeft.PtInRect(pt) ? L"TRUE" : L"FALSE");
		TRACE(L"DOWNRIGHT - %s", m_rcDownRight.PtInRect(pt) ? L"TRUE" : L"FALSE");

		if (!m_rcUpLeft.PtInRect(pt) && !m_rcDownRight.PtInRect(pt))
		{
			KillTimer(IDT_MOUSE_LEAVE);
			m_bTimerSet = FALSE;
			m_bUpLeftFocus = FALSE;
			m_bDownRightFocus = FALSE;
			Invalidate(FALSE);
		}
	}

	CSpinButtonCtrl::OnTimer(nIDEvent);
}
